package com.jykj.modbus.system.runtime.hibernate;

import org.hibernate.Criteria;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.hibernate.query.Query;
import org.hibernate.transform.Transformers;
import org.springframework.stereotype.Repository;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.List;
import java.util.Map;

/**
 * HibernateDao 基础类
 */
@Repository
public class BaseDao {


    @Resource
    public SessionFactory sessionFactory;



    public Session getCurrentSession() {
        return sessionFactory.getCurrentSession();
    }

    /**
     * 保存
     *
     * @param object
     * @throws
     */
    public void save(Object object) {
        getCurrentSession().save(object);
    }

    /**
     * 修改
     *
     * @param object
     * @return void
     * @throws
     */
    public void update(Object object) {
        getCurrentSession().update(object);
    }

    /**
     * 保存返回ID
     *
     * @param object
     * @return Serializable
     * @throws
     */
    public Serializable saveReturnPk(Object object) {
        Serializable pk = -1;
        pk = getCurrentSession().save(object);
        return pk;
    }

    /**
     * 保存或者修改
     *
     * @param object
     * @throws

     */
    public void saveOrUpdate(Object object) {
        getCurrentSession().saveOrUpdate(object);
    }

    /**
     * 根据主键ID获取实体数据
     *
     * @param entityClass
     * @param id
     * @return T
     * @throws
     */
    @SuppressWarnings("unchecked")
    public <T> T getById(Class<T> entityClass, Serializable id) {
        return (T) getCurrentSession().get(entityClass, id);
        //return (T)sessionFactory.openSession().get(entityClass, id);
    }

    /**
     * 根据ID删除数据
     *
     * @param entityClass
     * @param id
     * @throws
     */
    public <T> void removeById(Class<T> entityClass, Serializable id) {
        T entity = getById(entityClass, id);
        remove(entity);
    }

    /**
     * 根据实体删除数据
     *
     * @param object
     * @throws
     */
    public void remove(Object object) {
        getCurrentSession().delete(object);
    }

    /**
     * 创建Query对象
     *
     * @param values 0~N个参数
     *               <pre>
     *                                                  dao.createQuery(hql)
     *                                                  dao.createQuery(hql,arg0);
     *                                                  dao.createQuery(hql,arg0,arg1);
     *                                                  dao.createQuery(hql,new Object[arg0,arg1,arg2])
     *                                           </pre>
     */
    public Query createQuery(String hql, Object... values) {
        Assert.hasText(hql);
        //Query query = sessionFactory.openSession().createQuery(hql);
        Query query = getCurrentSession().createQuery(hql);
        for (int i = 0; i < values.length; i++) {
            query.setParameter(i, values[i]);
        }
        return query;
    }

    /**
     * 消除与 Hibernate Session 的关联
     *
     * @param entity
     * @return void
     * @throws
     */
    public void evit(Object entity) {
        getCurrentSession().evict(entity);
    }

    /**
     * 创建Criteria对象
     *
     * @param entityClass
     * @param criterions
     * @return Criteria
     * @throws
     */
    public <T> Criteria createCriteria(Class<T> entityClass, Criterion... criterions) {
        Criteria criteria = getCurrentSession().createCriteria(entityClass);
        for (Criterion c : criterions) {
            criteria.add(c);
        }
        return criteria;
    }

    /**
     * 根据属性名和属性值查询对象
     *
     * @param entityClass
     * @param propertyName
     * @param value
     * @return List<T>
     * @throws
     */
    @SuppressWarnings("unchecked")
    public <T> List<T> findByProperty(Class<T> entityClass, String propertyName, Object value) {
        Assert.hasText(propertyName);
        return createCriteria(entityClass, Restrictions.eq(propertyName, value)).list();
    }

    /**
     * 根据属性名和属性值查询唯一对象
     *
     * @param entityClass
     * @param propertyName
     * @param value
     * @return T
     * @throws
     */
    @SuppressWarnings("unchecked")
    public <T> T findUniqueBy(Class<T> entityClass, String propertyName, Object value) {
        Assert.hasText(propertyName);
        return (T) createCriteria(entityClass, Restrictions.eq(propertyName, value)).uniqueResult();
    }

    /**
     * 根据id查询
     *
     * @param clazz
     * @param id
     * @return Object
     * @throws
     */
    public Object find(Class clazz, Integer id) {
        return getCurrentSession().get(clazz, id);
    }

    /**
     * 获得结果集 HQL
     *
     * @param hql    HQL语句
     * @param params 参数
     * @return 结果集
     */
    @SuppressWarnings("unchecked")
    public <T> List<T> findByHql(String hql, Map<String, Object> params, int page, int rows) {
        Assert.hasText(hql);
        Query query = getCurrentSession().createQuery(hql);
        if (params != null && !params.isEmpty()) {
            for (String key : params.keySet()) {
                query.setParameter(key, params.get(key));
            }
        }
        query.setFirstResult((page - 1) * rows);//开始从第几条开始取数据
        query.setMaxResults(rows);//取多少条数据
        return query.list();
    }
    public <T> List<T> findByHql(String hql, Map<String, Object> params) {
        Assert.hasText(hql);
        Query query = getCurrentSession().createQuery(hql);
        if (params != null && !params.isEmpty()) {
            for (String key : params.keySet()) {
                query.setParameter(key, params.get(key));
            }
        }
        return query.list();
    }
    /**
     * 获得结果集 SQL
     *
     * @param sql    SQL语句
     * @param params 参数
     * @return 结果集
     */
    @SuppressWarnings("unchecked")
    public <T> List<T> findBySql(String sql, Map<String, Object> params, int page, int rows) {
        SQLQuery q = getCurrentSession().createSQLQuery(sql);
        if (params != null && !params.isEmpty()) {
            for (String key : params.keySet()) {
                q.setParameter(key, params.get(key));
            }
        }
        return q.setFirstResult((page - 1) * rows).setMaxResults(rows).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
    }

    /**
     * 获得结果集 SQL(不分页)
     *
     * @param sql    SQL语句
     * @param params 参数
     * @return 结果集
     */
    @SuppressWarnings("unchecked")
    public <T> List<T> findBySqlNoLimet(String sql, Map<String, Object> params) {
        SQLQuery q = getCurrentSession().createSQLQuery(sql);
        if (params != null && !params.isEmpty()) {
            for (String key : params.keySet()) {
                q.setParameter(key, params.get(key));
            }
        }
        return q.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
    }
    /**
     * 统计 HQL
     *
     * @param hql    HQL语句
     * @param params 参数
     * @return 数目
     */
    @SuppressWarnings("unchecked")
    public Long countByHql(String hql, Map<String, Object> params) {
        Assert.hasText(hql);
        Query query = getCurrentSession().createQuery(hql);
        if (params != null && !params.isEmpty()) {
            for (String key : params.keySet()) {
                query.setParameter(key, params.get(key));
            }
        }
        Object o = query.uniqueResult();
        return Long.parseLong(o.toString());
    }
    /**
     * 统计 SQL
     *
     * @param sql    SQL语句
     * @param params 参数
     * @return 数目
     */
    @SuppressWarnings("unchecked")
    public Long countBySql(String sql, Map<String, Object> params) {
        SQLQuery q = getCurrentSession().createSQLQuery(sql);
        if (params != null && !params.isEmpty()) {
            for (String key : params.keySet()) {
                q.setParameter(key, params.get(key));
            }
        }
        Object o= q.uniqueResult();
        return Long.parseLong(o.toString());
    }
    /**
     * 获得结果集 HQL
     *(验证是否有数组)
     * @param hql    HQL语句
     * @param params 参数
     * @return 结果集
     */
    @SuppressWarnings("unchecked")
    public <T> List<T> findByHql2(String hql, Map<String, Object> params,String strs,Integer[] ids ,int page, int rows) {
        Assert.hasText(hql);
        Query query = getCurrentSession().createQuery(hql);
        if (params != null && !params.isEmpty()) {
            for (String key : params.keySet()) {
                if(key.equals(strs)){
                    query.setParameterList(key, ids);
                }else {
                    query.setParameter(key, params.get(key));
                }

            }
        }
        query.setFirstResult((page - 1) * rows);//开始从第几条开始取数据
        query.setMaxResults(rows);//取多少条数据
        return query.list();
    }

    /**
     * 获得结果集 HQL
     *(验证是否有数组)(不分页)
     * @param hql    HQL语句
     * @param params 参数
     * @return 结果集
     */
    @SuppressWarnings("unchecked")
    public <T> List<T> findByHql3(String hql, Map<String, Object> params,String strs,Integer[] ids) {
        Assert.hasText(hql);
        Query query = getCurrentSession().createQuery(hql);
        if (params != null && !params.isEmpty()) {
            for (String key : params.keySet()) {
                if(key.equals(strs)){
                    query.setParameterList(key, ids);
                }else {
                    query.setParameter(key, params.get(key));
                }

            }
        }
        return query.list();
    }
    /**
     * 统计 HQL
     *
     * @param hql    HQL语句
     * @param params 参数
     * @return 数目
     */
    @SuppressWarnings("unchecked")
    public Long countByHql2(String hql, Map<String, Object> params,String strs,Integer[] ids) {
        Assert.hasText(hql);
        Query query = getCurrentSession().createQuery(hql);
        if (params != null && !params.isEmpty()) {
            for (String key : params.keySet()) {
                if(key.equals(strs)){
                    query.setParameterList(key, ids);
                }else {
                    query.setParameter(key, params.get(key));
                }
            }
        }
        Object o = query.uniqueResult();
        return Long.parseLong(o.toString());
    }
    /**
     * 获得结果集 SQL
     *
     * @param sql    SQL语句
     * @param params 参数
     * @return 结果集
     */
    @SuppressWarnings("unchecked")
    public <T> List<T> findBySql2(String sql, Map<String, Object> params,String strs,Integer[] ids ,int page, int rows) {
        Query q = getCurrentSession().createSQLQuery(sql);
        if (params != null && !params.isEmpty()) {
            for (String key : params.keySet()) {
                if(key.equals(strs)){
                    q.setParameterList(key, ids);
                }else {
                    q.setParameter(key, params.get(key));
                }
            }
        }
        return q.setFirstResult((page - 1) * rows).setMaxResults(rows).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
    }
    /**
     * 统计 SQL
     *
     * @param sql    SQL语句
     * @param params 参数
     * @return 数目
     */
    @SuppressWarnings("unchecked")
    public Long countBySql2(String sql, Map<String, Object> params,String strs,Integer[] ids) {
        SQLQuery q = getCurrentSession().createSQLQuery(sql);
        if (params != null && !params.isEmpty()) {
            for (String key : params.keySet()) {
                if(key.equals(strs)){
                    q.setParameterList(key, ids);
                }else {
                    q.setParameter(key, params.get(key));
                }
            }
        }
        Object o= q.uniqueResult();
        return Long.parseLong(o.toString());
    }
}

